// import express from 'express'
var crypto = require('crypto')
var app = require('express')()
var cookieParser = require('cookie-parser')
var bodyParser = require('body-parser')
var server = require('http').Server(app)
var wsServer = require('socket.io')(server, {
  path: '/game',
  serveClient: false,
  pingInterval: 10000,
  pingTimeout: 5000,
  cookie: false
})

if (process.env.NODE_ENV === 'development') {

}

var webpack = require('webpack')
var webpackDevMiddleware = require('webpack-dev-middleware')

var webpackConfig = require('./config/webpack.dev.js')
var compiler = webpack(webpackConfig)

console.log(webpackConfig.output.publicPath)
var devMiddleware = webpackDevMiddleware(compiler, {
  publicPath: '/'
})
app.use(devMiddleware)
app.use(cookieParser())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))

var HTTP_PORT = 18080
var WS_PORT = 80
console.log('> Starting dev server...')
app.listen(HTTP_PORT, function () {
  console.log('> Http server listening at port ' + HTTP_PORT + '\n')
})

var globalUsers = {
  // online: 0,
  total: 0,
  dict: {}
}

var token2user = {}
var socket2user = {}

// 登出
app.get('/logout', function (req, res) {
  res.status(401)
  res.end()
})

// 登录/注册
app.post('/auth', function (req, res) {
  var key = req.headers.authorization
  if (key) {
    var userName = Buffer.from(key.replace('Basic ', ''), 'base64').toString().split(':')[0]
    var userInfo = globalUsers.dict[key]
    var userId = null
    if (userInfo) {
      userId = userInfo.userId
    } else {
      globalUsers.total++
      // var md5 = crypto.createHash('md5')
      // md5.update(key)
      // encryptString = hasher.digest('hex')
      userId = key
      userInfo = {
        userId: userId,
        userName: userName,
        room: req.body.room
      }
      globalUsers.dict[key] = userInfo
    }
    // 创建临时userToken，一分钟后失效
    var userToken = Date.now() + '->' + userId
    token2user[userToken] = userId
    setTimeout(function () {
      delete token2user[userToken]
    }, 60000)
    res.cookie('userToken', userToken, {maxAge: 60000, path: '/', httpOnly: true})
    res.json({
      success: true,
      data: {
        userToken: userToken
      }
    })
  } else {
    res.set({
      'WWW-Authenticate': 'Basic'
    })
    res.status(401)
    res.end()
  }
})

server.listen(WS_PORT, function () {
  console.log('> WebSocket server listening at port ' + WS_PORT + '\n')
})

var defaultWsServer = wsServer.of('/')
var chatWsServer = wsServer.of('/chat')
var gameWsServer = wsServer.of('/game')

// 鉴权
gameWsServer.use(function (socket, next) {
  var userToken = socket.conn.request._query.userToken
  var userId = token2user[userToken]
  if (userId) {
    delete token2user[userToken] // 使用后立即失效
    socket2user[socket.id] = globalUsers.dict[userId]
    return next()
  } else {
    return next(new Error('Authentication error'))
  }
})

gameWsServer.on('connection', function (socket) {
  var userInfo = socket2user[socket.id]

  console.log(userInfo.userName + ' connected.')

  socket.join(userInfo.room, function (err) {
    if (err) {
      console.warn('加入房间' + userInfo.room + '失败。')
      console.error(err)
    } else {
      // 广播给房间内的其他人
      socket.broadcast.to(userInfo.room).emit('sys', userInfo.userName + '加入了房间')
      // 通知房间内的所有人
      // gameWsServer.in(userInfo.room).emit('sys', userInfo.userName + '加入了房间')
    }
  })

  var STAGE_WIDTH = 350
  var STAGE_HEIGHT = 350
  var ROOM_SIZE = 2

  var foodPosList = []
  socket.on('init game', function (data) {
    for (var i = 0; i < 100; i++) {
      foodPosList.push({
        x: Math.random() * (STAGE_WIDTH - 20) + 10,
        y: Math.random() * (STAGE_HEIGHT - 20) + 10,
      })
    }
    gameWsServer.in(userInfo.room).emit('init game', {
      snake: {},
      foodPosList: foodPosList
    })
    gameWsServer.in(userInfo.room).emit('start')
  })

  socket.on('ready', function (data) {
    userInfo.ready = true
    // 获取房间内其他人是否准备完毕
    gameWsServer.in(userInfo.room).clients(function (err, clients) {
      if (err) {
        console.error(err)
      } else {
        var u
        var readyCount = 0
        for (var i = 0; i < clients.length; i++) {
          u = socket2user[clients[i]]
          if (u.ready) {
            readyCount++
          } else {
            break
          }
        }
        if (readyCount === ROOM_SIZE) {
          gameWsServer.in(userInfo.room).emit('all ready', true)
        }
      }
    })
  })

  socket.on('my turn', function (myTurn) {
    // gameWsServer.to(userInfo.room).emit('his turn', myTurn)
    socket.broadcast.to(userInfo.room).emit('his turn', myTurn)
  })

  socket.on('leave', function () {
    socket.broadcast.to(userInfo.room).emit('leave', userInfo.userName + '离开了房间')
  })

})
